/***********************************************************************************************************************
 * ############################################# Application AdewebLite #############################################
 * AdewebLite Android est une application permettant de consulter des emplois du temps fournis par l'université UHP
 * avec ou sans connexion internet (informations gardées en mémoire à chaque synchronisation). Et utilisant la web
 * API ADE pour collecter les données.
 * @author Andrianjafintrimo Victor, Zanette Sébastien
 * 
 * Basée sur l'application du même nom, utilisant le flux RSS (données à traiter), de :
 * @author Schnell Michaël, Zanette Sébastien
 * **********************************************************************************************************************
 */

package ade.prime.model;

import java.util.Iterator;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Structure pour une liste de {@code Lesson}.
 * Une instance de {@code Lessons} connait une liste de {@code Lesson}
 * Contient un ensemble de fonctions permettant d'ajouter/supprimer/obtenir une {@code Lesson} à la liste, ansi que les fonction permettant d'itérer une liste de {@code Lesson}
 * @author Zanette Sébastien, @author Andrianjafintrimo Victor
 */
public class Lessons implements Iterable<Lesson>, Parcelable {
	
	public static final Parcelable.Creator<Lessons> CREATOR = new Creator<Lessons>() {
		
		@Override
		public Lessons[] newArray(int size) {
			return new Lessons[size] ;
		}
		
		@Override
		public Lessons createFromParcel(Parcel source) {
			return new Lessons(source) ;
		}
	};

	private Lesson[] lessons ;
	private int nLessons ;

	/**
	 * Constructeur de la classe {@code Lessons}, permet d'initialiser les champ
	 */
	public Lessons () {
		this(new Lesson[0]) ;
	}// Lessons()
	
	public Lessons(Parcel in) {
		super() ;
		this.nLessons = in.readInt() ;
		this.lessons = new Lesson[this.nLessons] ;
		in.readTypedArray(this.lessons, Lesson.CREATOR) ;
	}
	
	public Lessons(Lesson[] lessons) {
		super() ;
		this.nLessons = lessons.length ;
		this.lessons = lessons ;
	}

	/**
	 * Vérifie que la liste est assez grande pour le nombre d'éléments donnés
	 * Si la liste est trop petite, une nouvelle est créée et mis à null 
	 * 
	 * @param 	size
	 */
	public void ensureCapacity (int size) {
		if (size > this.lessons.length) {
			Lesson[] tmp = new Lesson[size] ;
			for(int l = 0; l < this.lessons.length; l++) {
				tmp[l] = this.lessons[l] ;
			}// for
			for(int l = this.lessons.length; l < tmp.length; l++) {
				tmp[l] = null ;
			}// for
			this.lessons = tmp ;
		}// if
	}// ensureCapacity()

	/**
	 * Insère un nouveau cours, en utilisant l'algorithme d'insertion trié
	 * @param 	l
	 * 			{@code Lesson} à ajouter
	 */
	public void insert (Lesson l) {
		int pos = this.nLessons ;
		while ((pos > 0) && (this.lessons[pos-1].compareTo(l) > 0)) {
			this.lessons[pos] = this.lessons[pos-1] ;
			--pos ;
		}// while
		this.lessons[pos] = l ;
		this.nLessons++ ;
	}// insert(Lesson)

	/**
	 * Ajoute un nouveau cours à la fin de la liste des cours
	 * @param 	l
	 * 			Lesson à ajouter
	 */
	public void append (Lesson l) {
		this.lessons[this.nLessons] = l ;
		this.nLessons++ ;
	}// append(Lesson)

	/**
	 * Retourne le nombre de cours
	 * @return  Nombre de cours
	 */
	public int size () {
		return this.nLessons ;
	}// size()

	/**
	 * Retourne le cours se trouvant à l'indice donné en paramètre
	 * @param i indice du cours recherché
	 * @return la {@code Lesson} se trouvant à l'indice i
	 */
	public Lesson get(int i) {
		return this.lessons[i] ;
	}// get(int)

	/**
	 * Permet d'obtenir un itérateur de {@code Lessson}
	 * @return un itérateur de {@code Lesson}
	 */
	@Override
	public Iterator<Lesson> iterator() {
		return new LessonIterator(this) ;
	}

	/**
	 * Classe LessonIterator, correspondant à un itérateur de {@code Lesson}
	 */
	class LessonIterator implements Iterator<Lesson> {

		protected int next ;
		protected Lessons lessons ;

		/**
		 * Constructeur de {@code LessonIterator} permet d'initialiser les champ
		 * @param lessons initilise les {@code Lessons} sur lesquelles on va itérer
		 */
		public LessonIterator(Lessons lessons) {
			this.next = 0 ;
			this.lessons = lessons ;
		}

		/**
		 * Permet de savoir si il existe une {@code Lesson} suivante
		 * @return true si il existe une {@code Lesson} suivante, false sinon
		 */
		@Override
		public boolean hasNext() {
			return (this.next < this.lessons.size()) ;
		}

		/**
		 * Permet d'obtenir la {@code Lesson} suivante
		 * @return la {@code Lesson} suivante lorsque'on itére
		 */
		@Override
		public Lesson next() {
			int next = this.next ;
			this.next++ ;
			return this.lessons.get(next) ;
		}

		/**
		 * Supprime une {@code Lesson}
		 */
		@Override
		public void remove() {
			throw new UnsupportedOperationException("LessonIterator.remove n'a pas été implanté.") ;
		}

	}

	/* (non-Javadoc)
	 * @see android.os.Parcelable#describeContents()
	 */
	@Override
	public int describeContents() {
		return 0;
	}

	/* (non-Javadoc)
	 * @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
	 */
	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeInt(this.nLessons) ;
		dest.writeTypedArray(this.lessons, 0) ;
	}

}// Class Lessons